package core

import (
	"encoding/json"
	"errors"
	"flag"
	"github.com/geekerstar/libv/av"
	"io/ioutil"
	"live-core/logging"
	"log"
	"net"
	"sync"
	"time"
)

const (
	MSE = iota
	WEBRTC
	RTSP
)

const (
	OFFLINE = iota
	ONLINE
)

//var debug bool
var (
	Success                         = "成功"
	ErrorStreamNotFound             = errors.New("没有找到摄像头")
	ErrorStreamAlreadyExists        = errors.New("摄像头已存在")
	ErrorStreamChannelAlreadyExists = errors.New("摄像头通道已存在")
	ErrorStreamNotHLSSegments       = errors.New("摄像头分片流文件丢失")
	ErrorStreamNoVideo              = errors.New("摄像头无视频流")
	ErrorStreamNoClients            = errors.New("摄像头没有访问权限")
	ErrorStreamRestart              = errors.New("摄像头重启")
	ErrorStreamStopCoreSignal       = errors.New("摄像头信令丢失")
	ErrorStreamStopRTSPSignal       = errors.New("摄像头RTSP流丢失")
	ErrorStreamChannelNotFound      = errors.New("摄像头通道未找到")
	ErrorStreamChannelCodecNotFound = errors.New("摄像头通道编解码器未就绪，原因可能是视频编码不支持")
	ErrorStreamsLen0                = errors.New("摄像头取流失败")
	DefaultHTTPDir                  = "web"
	StreamManager                   *StorageST
)

type StorageST struct {
	mutex   sync.RWMutex
	Server  ServerST            `json:"server" groups:"api,config"`
	Streams map[string]StreamST `json:"streams" groups:"api,config"`
}

type ServerST struct {
	Debug         bool   `json:"debug" groups:"api,config"`
	LogLevel      string `json:"log_level" groups:"api,config"`
	HTTPDemo      bool   `json:"http_demo" groups:"api,config"`
	HTTPDebug     bool   `json:"http_debug" groups:"api,config"`
	HTTPLogin     string `json:"http_login" groups:"api,config"`
	HTTPPassword  string `json:"http_password" groups:"api,config"`
	HTTPDir       string `json:"http_dir" groups:"api,config"`
	HTTPPort      string `json:"http_port" groups:"api,config"`
	RTSPPort      string `json:"rtsp_port" groups:"api,config"`
	HTTPS         bool   `json:"https" groups:"api,config"`
	HTTPSPort     string `json:"https_port" groups:"api,config"`
	HTTPSCert     string `json:"https_cert" groups:"api,config"`
	HTTPSKey      string `json:"https_key" groups:"api,config"`
	WebRTCPortMin uint16 `json:"udp_port_min" groups:"api,config"`
	WebRTCPortMax uint16 `json:"udp_port_max" groups:"api,config"`
}

type StreamST struct {
	Name     string               `json:"name,omitempty" groups:"api,config"`
	Channels map[string]ChannelST `json:"channels,omitempty" groups:"api,config"`
}

type ChannelST struct {
	Name             string `json:"name,omitempty" groups:"api,config"`
	URL              string `json:"url,omitempty" groups:"api,config"`
	OnDemand         bool   `json:"on_demand,omitempty" groups:"api,config"`
	Debug            bool   `json:"debug,omitempty" groups:"api,config"`
	Status           int    `json:"status,omitempty" groups:"api"`
	runLock          bool
	codecs           []av.CodecData
	sdp              []byte
	signals          chan int
	hlsSegmentBuffer map[int]Segment
	hlsSegmentNumber int
	clients          map[string]ClientST
	ack              time.Time
}

type ClientST struct {
	mode              int
	signals           chan int
	outgoingAVPacket  chan *av.Packet
	outgoingRTPPacket chan *[]byte
	socket            net.Conn
}

type Segment struct {
	dur  time.Duration
	data []*av.Packet
}

// InitStreamManager 根据配置文件做初始化工作
// 初始化流程管理器
func InitStreamManager() {
	//运行参数
	argConfigPatch := flag.String("配置文件", "config.json", "配置config.json")
	//argDebug := flag.Bool("调试模式", false, "设置调试模式")
	//debug = *argDebug
	flag.Parse()
	var tmp StorageST
	data, err := ioutil.ReadFile(*argConfigPatch)
	if err != nil {
		log.Fatal(err)
	}
	err = json.Unmarshal(data, &tmp)
	if err != nil {
		log.Fatal(err)
	}
	//初始化日志
	logging.InitZap(tmp.ServerLogLevel())

	//debug = tmp.Server.Debug
	for i, i2 := range tmp.Streams {
		for i3, i4 := range i2.Channels {
			i4.clients = make(map[string]ClientST)
			i4.ack = time.Now().Add(-255 * time.Hour)
			i4.hlsSegmentBuffer = make(map[int]Segment)
			i4.signals = make(chan int, 100)
			i2.Channels[i3] = i4
		}
		tmp.Streams[i] = i2
	}

	StreamManager = &tmp
}
